package edu.chalmers.targine;

import java.nio.ByteBuffer;
import java.nio.ByteOrder;
import java.nio.FloatBuffer;

import javax.microedition.khronos.opengles.GL10;
import javax.microedition.khronos.opengles.GL11;

public class Billboard {
	public float x, y, z;
	public float xRot, yRot, zRot;
	public float scale;
	public int texID;
	private FloatBuffer vertexBuffer;	// buffer holding the vertices
	private FloatBuffer textureBuffer;	// buffer holding the texture coordinates
	
	public Billboard(int texID, float x, float y, float z, float scale, float xRot){
		this.texID = texID;
		this.x = x;
		this.y = y;
		this.z = z;
		this.scale = scale;
		this.xRot = xRot;
//		xRot = yRot = zRot = 0f;
		
		initBillboard();
	}
	
	private void initBillboard(){
		float vertices[] = {
				-1.0f, -1.0f,  0.0f,		// V1 - bottom left
				-1.0f,  1.0f,  0.0f,		// V2 - top left
				 1.0f, -1.0f,  0.0f,		// V3 - bottom right
				 1.0f,  1.0f,  0.0f			// V4 - top right
		};

		float texture[] = {
				// Mapping coordinates for the vertices
				0.0f, 1.0f,		// top left		(V2)
				0.0f, 0.0f,		// bottom left	(V1)
				1.0f, 1.0f,		// top right	(V4)
				1.0f, 0.0f		// bottom right	(V3)
		};
		
		// a float has 4 bytes so we allocate for each coordinate 4 bytes
		ByteBuffer byteBuffer = ByteBuffer.allocateDirect(vertices.length * 4);
		byteBuffer.order(ByteOrder.nativeOrder());
		vertexBuffer = byteBuffer.asFloatBuffer();
		vertexBuffer.put(vertices);
		vertexBuffer.position(0);

		byteBuffer = ByteBuffer.allocateDirect(texture.length * 4);
		byteBuffer.order(ByteOrder.nativeOrder());
		textureBuffer = byteBuffer.asFloatBuffer();
		textureBuffer.put(texture);
		textureBuffer.position(0);
	}
	
	public void draw(GL10 gl){
		float[] modelview = new float[16];
		int i, j;
		
		// save the current modelview matrix
		gl.glPushMatrix();
		// get the current modelview matrix
		((GL11)gl).glGetFloatv(GL11.GL_MODELVIEW_MATRIX, modelview, 0);
		// undo all rotations, beware all scaling is lost as well 
		for( i=0; i<3; i++ ){
			for( j=0; j<3; j++ ){
				if ( i==j ){
					modelview[i*4+j] = 1.0f;
				} else{
					modelview[i*4+j] = 0.0f;
				}
			}
		}
		// set the modelview with no rotations and scaling
		gl.glLoadMatrixf(modelview, 0);
		
		gl.glTranslatef(x, y, z);
		gl.glScalef(scale, scale, scale);
		gl.glRotatef(xRot, 0, 0, 1);

		//enable png transparency
        gl.glEnable(GL10.GL_BLEND);
//        gl.glBlendFunc(GL10.GL_ONE, GL10.GL_ONE_MINUS_SRC_ALPHA);
        gl.glBlendFunc(GL10.GL_SRC_ALPHA, GL10.GL_ONE_MINUS_SRC_ALPHA);
		/** The draw method for the square with the GL context */
		gl.glEnable(GL10.GL_TEXTURE_2D);
		// bind the previously generated texture
		gl.glBindTexture(GL10.GL_TEXTURE_2D, texID);
				
		gl.glEnableClientState(GL10.GL_VERTEX_ARRAY);
		gl.glEnableClientState(GL10.GL_TEXTURE_COORD_ARRAY);

		// Point to our vertex buffer
		gl.glVertexPointer(3, GL10.GL_FLOAT, 0, vertexBuffer);
		gl.glTexCoordPointer(2, GL10.GL_FLOAT, 0, textureBuffer);

		// Draw the vertices as triangle strip
		gl.glDrawArrays(GL10.GL_TRIANGLE_STRIP, 0, 4);

		//Disable the client state before leaving
		gl.glDisableClientState(GL10.GL_VERTEX_ARRAY);
		gl.glDisableClientState(GL10.GL_TEXTURE_COORD_ARRAY);
		gl.glDisable(GL10.GL_BLEND);
		
		// restores the modelview matrix
		gl.glPopMatrix();
	}
}
